﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HalconDotNet;
using System.Windows.Forms;
namespace unite
{
    class HDevelopExport
    {
        // Main procedure 
        HTuple hv_CameraPose = new HTuple();
        HTuple hv_CameraParameters = new HTuple();
        /// <summary>
        /// 标定函数
        /// </summary>
        /// <param name="Window">显示窗口句柄</param>
        /// <param name="File">图像路径</param>
        /// <param name="DescriptionFilePath">描述文件路径</param>
        /// <param name="CameraType">相机类型</param>
        /// <param name="Focus">焦距</param>
        /// <param name="Thickness">标定板厚度</param>
        /// <param name="Sx">单个像素宽度Sx</param>
        /// <param name="Sy">单个像素高度Sy</param>
        /// <param name="Cx">图像宽Cx</param>
        /// <param name="Cy">图像高Cy</param>
#region
        public void Action(HTuple Window, string[] File, string DescriptionFilePath, string CameraType, double Focus, double Thickness, double Sx, double Sy, int Cx, int Cy)
        {
            // Local iconic variables 
            HObject ho_Image = null;
            // Local control variables 
            HObject ho_EmptyObject;
            HObject ho_Contours, ho_Cross;
            //HTuple hv_ImageFiles = null, hv_TmpCtrl_ReferenceIndex = null;
            HTuple hv_Width, hv_Height;
            HTuple hv_Row1 = new HTuple(), hv_Column = new HTuple();
            HTuple hv_Pose = new HTuple(), hv_i = new HTuple(), hv_Index1=new HTuple();
            // Initialize local and output iconic variables 
            HOperatorSet.GenEmptyObj(out ho_Image);
            HOperatorSet.GenEmptyObj(out ho_EmptyObject);
            HOperatorSet.GenEmptyObj(out ho_Contours);
            HOperatorSet.GenEmptyObj(out ho_Cross);
            //Calibration 01: Code generated by Calibration 01
            HTuple hv_TmpCtrl_ReferenceIndex = 0;
            HTuple hv_TmpCtrl_PlateDescription = DescriptionFilePath;
            HTuple hv_StartParameters = new HTuple();
            hv_StartParameters[0] = Focus;
            hv_StartParameters[1] = 0;
            hv_StartParameters[2] = Sx;
            hv_StartParameters[3] = Sy;
            hv_StartParameters[4] = Cx / 2;
            hv_StartParameters[5] = Cy / 2;
            hv_StartParameters[6] = Cx;
            hv_StartParameters[7] = Cy;
            HTuple hv_TmpCtrl_FindCalObjParNames = new HTuple();
            hv_TmpCtrl_FindCalObjParNames[0] = "gap_tolerance";
            hv_TmpCtrl_FindCalObjParNames[1] = "alpha";
            hv_TmpCtrl_FindCalObjParNames[2] = "skip_find_caltab";
            HTuple hv_TmpCtrl_FindCalObjParValues = new HTuple();
            hv_TmpCtrl_FindCalObjParValues[0] = 1;
            hv_TmpCtrl_FindCalObjParValues[1] = 1;
            hv_TmpCtrl_FindCalObjParValues[2] = "false";
            HTuple hv_CalibHandle;
            //Calibration 01: Create calibration model for managing calibration data
            HOperatorSet.CreateCalibData("calibration_object", 1, 1, out hv_CalibHandle);
            HOperatorSet.SetCalibDataCamParam(hv_CalibHandle, 0, CameraType, hv_StartParameters);
            HOperatorSet.SetCalibDataCalibObject(hv_CalibHandle, 0, hv_TmpCtrl_PlateDescription);
            HTuple hv_Index;
            //Calibration 01: Collect mark positions and estimated poses for all plates
            for (hv_Index = 0; hv_Index < File.Length; hv_Index++)
            {
                ho_EmptyObject.Dispose();
                HOperatorSet.GenEmptyObj(out ho_EmptyObject);
                ho_Image.Dispose();
                HOperatorSet.ReadImage(out ho_Image, File[hv_Index]);
                HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
                HOperatorSet.SetPart(Window, 0, 0, hv_Height - 1, hv_Width - 1);
                HOperatorSet.FindCalibObject(ho_Image, hv_CalibHandle, 0, 0, hv_Index, hv_TmpCtrl_FindCalObjParNames,
                  hv_TmpCtrl_FindCalObjParValues);
                ho_Contours.Dispose();
                HOperatorSet.GetCalibDataObservContours(out ho_Contours, hv_CalibHandle, "caltab",
                  0, 0, hv_Index);
                hv_Row1.Dispose(); hv_Column.Dispose(); hv_Index1.Dispose(); hv_Pose.Dispose();
                HOperatorSet.GetCalibDataObservPoints(hv_CalibHandle, 0, 0, hv_Index, out hv_Row1,
                      out hv_Column, out hv_Index1, out hv_Pose);
                for (hv_i = 0; (int)hv_i <= (int)((new HTuple(hv_Index1.TupleLength())) - 1); hv_i = (int)hv_i + 1)
                {
                    using (HDevDisposeHelper dh = new HDevDisposeHelper())
                    {
                        ho_Cross.Dispose();
                        HOperatorSet.GenCrossContourXld(out ho_Cross, hv_Row1.TupleSelect(hv_i),
                            hv_Column.TupleSelect(hv_i), 20, 0);
                    }
                    {
                        HObject ExpTmpOutVar_0;
                        HOperatorSet.ConcatObj(ho_EmptyObject, ho_Cross, out ExpTmpOutVar_0);
                        ho_EmptyObject.Dispose();
                        ho_EmptyObject = ExpTmpOutVar_0;
                    }
                }
                HOperatorSet.DispObj(ho_Image, Window);
                HOperatorSet.DispObj(ho_EmptyObject, Window);
                HOperatorSet.DispObj(ho_Contours, Window);
                HOperatorSet.WaitSeconds(0.3);
            }
            HTuple hv_TmpCtrl_Errors;
            //Calibration 01: Perform the actual calibration
            HOperatorSet.CalibrateCameras(hv_CalibHandle, out hv_TmpCtrl_Errors);
            HOperatorSet.GetCalibData(hv_CalibHandle, "camera", 0, "params", out hv_CameraParameters);
            HOperatorSet.GetCalibData(hv_CalibHandle, "calib_obj_pose", (new HTuple(0)).TupleConcat(
                hv_TmpCtrl_ReferenceIndex), "pose", out hv_CameraPose);
            //Calibration 01: Adjust origin for plate thickness
            HOperatorSet.SetOriginPose(hv_CameraPose, 0.0, 0.0, Thickness, out hv_CameraPose);
            //Calibration 01: Clear calibration model when done
            HOperatorSet.ClearCalibData(hv_CalibHandle);
            MessageBox.Show("标定成功","提示");
            // stop(); only in hdevelop
            //ho_Image.Dispose();
            //ho_EmptyObject.Dispose();
            //ho_Image.Dispose();
            //ho_Contours.Dispose();
            //ho_Cross.Dispose();
            //hv_TmpCtrl_ReferenceIndex.Dispose();
            //hv_TmpCtrl_PlateDescription.Dispose();
            //hv_StartParameters.Dispose();
            //hv_TmpCtrl_FindCalObjParNames.Dispose();
            //hv_TmpCtrl_FindCalObjParValues.Dispose();
            //hv_CalibHandle.Dispose();
            //hv_Index.Dispose();
            //hv_Row1.Dispose();
            //hv_Column.Dispose();
            //hv_Index1.Dispose();
            //hv_Pose.Dispose();
            //hv_i.Dispose();
            //hv_TmpCtrl_Errors.Dispose();
            //hv_CameraParameters.Dispose();
            //hv_CameraPose.Dispose();
        }
#endregion
        public void SaveParameters()
        {
            HOperatorSet.WriteCamPar(hv_CameraParameters, "D:/Halcon/CameraParameters.cal");
            HOperatorSet.WritePose(hv_CameraPose, "D:/Halcon/CameraPose.dat");
        }
    }
}
